package com.example.hello.views;

import com.example.hello.*;
import com.example.hello.POJO.UserPOJO;
import com.example.hello.views.users.Users;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Notification;
import com.vaadin.ui.VerticalLayout;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

import java.io.IOException;
import java.util.Set;

public class ManageUsersView extends VerticalLayout implements View {

    public static final String NAME = "users/manage";

    private HorizontalLayout layout = new HorizontalLayout();

    private BootstrapTabPanel tabPanel = new BootstrapTabPanel(BootstrapTabPanel.Position.ABOVE);
    protected BootstrapTabLink manageUsersLink = new BootstrapTabLink("Manage users");
    protected BootstrapTabLink createUserLink = new BootstrapTabLink("Create User");
    protected BootstrapTabPane manageUsersPane = new BootstrapTabPane();
    protected BootstrapTabPane createUserPane = new BootstrapTabPane();

    private final StringWrap selectedUser = new StringWrap();
    private final StringWrap selectedRole = new StringWrap();

    private final int height = 300;
    private final int maxHeight = 375;
    private final int buttonHeight = 30;
    private final int h4Height = 41;
    private final int optionHeight = 15;
    private final int formElement = 45;

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        if (!((HelloUI) HelloUI.getCurrent()).getUser().isSiteAdmin())
            getUI().getNavigator().navigateTo(Wireframe1.NAME);

        manageUsersLink.setActive(true);
        manageUsersPane.setActive(true);
    }

    public ManageUsersView() {
        setSizeFull();

        layout.setSizeFull();

        initTabPanel();
        initManagedUsers();
        initCreateUser();

        layout.addComponent(tabPanel);
        layout.setExpandRatio(tabPanel, 1);

        addComponent(layout);
    }

    public void initTabPanel() {
        tabPanel.setSizeFull();

        manageUsersLink.setTabPane(manageUsersPane);
        manageUsersPane.setHref("manageUsers");
        manageUsersLink.setDataTarget("manageUsers");
        createUserLink.setTabPane(createUserPane);
        createUserPane.setHref("createUser");
        createUserLink.setDataTarget("createUser");

        tabPanel.addTab(manageUsersLink);
        tabPanel.addTab(createUserLink);
        tabPanel.addTab(manageUsersPane);
        tabPanel.addTab(createUserPane);

        manageUsersLink.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                getUI().getNavigator().navigateTo(ManageUsersView.NAME);
            }
        });
        createUserLink.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                getUI().getNavigator().navigateTo(CreateUserView.NAME);
            }
        });
    }

    public void initManagedUsers() {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setHeight(height, Unit.PIXELS);

        final TextField firstName = new TextField("First Name");
        final TextField lastName = new TextField("Last Name");
        final ListBox roleMenu = new ListBox("Role");
        final TextField userName = new TextField("Username");
        final TextField password = new TextField("Password");

        // Get Users
        Set<UserPOJO> users = Users.getUsers();
//        try {
//            String json = HttpRequest.GET("users");
//            ObjectMapper mapper = new ObjectMapper();
//            users = mapper.readValue(json, new TypeReference<Set<UserPOJO>>() {
//            });
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        final Set<UserPOJO> usersCopy = users;

        // Choose and View User
        VerticalLayout left = new VerticalLayout();
        left.setHeight("100%");

        ListBox userList = new ListBox();
        final BootstrapButton viewProfile = new BootstrapButton("View Profile");
        viewProfile.setSize(BootstrapButton.Size.SMALL);

        userList.setVisibleItems((height - buttonHeight) / optionHeight);
        for (UserPOJO user : users) userList.addItem(user.getUserName());
        userList.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                if (event instanceof ListBoxChangeEvent) {
                    selectedUser.setString(((ListBoxChangeEvent) event).getSelected());

                    for (UserPOJO user : usersCopy) {
                        if (user.getUserName().equals(((ListBoxChangeEvent) event).getSelected())) {
                            userName.setValue(user.getUserName());
                            firstName.setValue(user.getFirstName());
                            lastName.setValue(user.getLastName());
                            password.setValue(user.getPassword());
                        }
                    }

                    viewProfile.setEnabled(true);
                }
            }
        });

        viewProfile.setEnabled(false);
        viewProfile.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                Notification.show(selectedUser.toString());
            }
        });

        left.addComponent(userList);
        left.addComponent(viewProfile);
        left.setExpandRatio(userList, 1);

        // Edit User
        layout.addComponent(left);
        layout.addComponent(new HSpacer(20));
        layout.addComponent(initRight("Update Profile", false,
                firstName, lastName, roleMenu, userName, password));

        manageUsersPane.addWidget(layout);
    }

    private void initCreateUser() {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setHeight(height, Unit.PIXELS);

        final TextField firstName = new TextField("First Name");
        final TextField lastName = new TextField("Last Name");
        final ListBox roleMenu = new ListBox("Role");
        final TextField userName = new TextField("Username");
        final TextField password = new TextField("Password");

        layout.addComponent(new HSpacer(240));
        layout.addComponent(initRight("Create User", true,
                firstName, lastName, roleMenu, userName, password));

        createUserPane.addWidget(layout);
    }

    private VerticalLayout initRight(String submitText, final boolean create,
                                     final TextField firstName,
                                     final TextField lastName,
                                     final ListBox roleMenu,
                                     final TextField userName,
                                     final TextField password) {
        VerticalLayout right = new VerticalLayout();
        right.setHeight("100%");

        GridLayout createUserPanel = new GridLayout();
        createUserPanel.setWidth("100%");

        String fieldWidth = "100px";
        Heading userInfo = new Heading("User Info", 4);
        userInfo.setContentMode(ContentMode.HTML);
        BootstrapButton submit = new BootstrapButton(submitText);
        firstName.setWidth(fieldWidth);
        lastName.setWidth(fieldWidth);
        roleMenu.setWidth(fieldWidth);
        userName.setWidth(fieldWidth);
        password.setWidth(fieldWidth);
        submit.setSize(BootstrapButton.Size.SMALL);

        roleMenu.addItem("Basic User");
        roleMenu.addItem("Assignment Administrator");
        roleMenu.addItem("Site Administrator");

        roleMenu.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                if (event instanceof ListBoxChangeEvent)
                    selectedRole.setString(((ListBoxChangeEvent) event).getSelected());
            }
        });

        submit.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                UserPOJO user = new UserPOJO();
                user.setFirstName(firstName.getValue());
                user.setLastName(lastName.getValue());
//                user.setRole(UserPOJO.Role.valueOf(selectedRole.toString()));
                user.setUserName(userName.getValue());
                user.setPassword(password.getValue());

                ObjectWriter objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
                String json = "";
                try {
                    json = objectWriter.writeValueAsString(user);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (create)
                    HttpRequest.executePut("users/" + user.getUserName(), json);
                else
                    HttpRequest.executePost("users/", json);
            }
        });
        TextField.enterKeyHandler(submit, firstName);
        TextField.enterKeyHandler(submit, lastName);
        TextField.enterKeyHandler(submit, userName);
        TextField.enterKeyHandler(submit, password);

        int area = (height - buttonHeight) / optionHeight;
        int removeFormElements = formElement * 5;
        int space = 9 - h4Height - removeFormElements;
        int variableHeight =  (area - 1) * optionHeight + space;

        int s = layout.getHeight() <= maxHeight ?
                variableHeight / 4 :
                18;
        createUserPanel.addComponent(firstName);
        createUserPanel.addComponent(new VSpacer(s));
        createUserPanel.addComponent(lastName);
        createUserPanel.addComponent(new VSpacer(s));
        createUserPanel.addComponent(roleMenu);
        createUserPanel.addComponent(new VSpacer(s));
        createUserPanel.addComponent(userName);
        createUserPanel.addComponent(new VSpacer(s));
        createUserPanel.addComponent(password);
        createUserPanel.addStyleName("border-form");

        right.addComponent(userInfo);
        right.addComponent(createUserPanel);
        right.addComponent(submit);
        right.setExpandRatio(createUserPanel, 1);

        return right;
    }

}
